package com.qinggeng.project.api.security.utils;

import com.qinggeng.common.constant.Constants;
import com.qinggeng.common.constant.HttpStatus;
import com.qinggeng.common.exception.CustomException;
import com.qinggeng.common.utils.IdUtils;
import com.qinggeng.common.utils.ServletUtils;
import com.qinggeng.common.utils.spring.SpringUtils;
import com.qinggeng.framework.redis.RedisCache;
import com.qinggeng.framework.security.LoginUser;
import com.qinggeng.project.system.domain.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.context.request.RequestAttributes;

import static com.qinggeng.common.constant.Constants.*;

/**
 * 接口端工具
 */
@Slf4j
public class ApiUtils {

    public final static String DEFAULT_ROLE_USER = "api_login_user";
    public final static String DEFAULT_ROLE_COURIER = "api_login_courier";

    public final static String DEFAULT_ROLE_ALL = "all";

    /**
     * 获取用户信息
     * @return
     */
    public static LoginUser getApiUser(){

        try {
            Object object = ServletUtils.getRequestAttributes().getAttribute(Constants.API_USERID, RequestAttributes.SCOPE_REQUEST);
            return SpringUtils.getBean(RedisCache.class).getCacheObject(object.toString());


        } catch (Exception e) {
            throw new CustomException("获取用户信息异常",HttpStatus.UNAUTHORIZED);
        }

    }



    public static String getApiRole(){
        return getApiUser().getRole();
    }


    public static Long getUserId(){
        return getApiUser().getUser().getUserId();
    }

    public static boolean getIsLogin(){
        try {
            LoginUser loginUser = getApiUser();
            if (loginUser == null){
                return false;
            }
            return true;
        }catch (Exception e){
            return false;
        }
    }

    public static void outLogin(String token){
         SpringUtils.getBean(RedisCache.class).deleteObject(getTokenKey(token));
         SpringUtils.getBean(RedisCache.class).deleteObject(getRoleTokenKey(token));
    }
    /**
     * 生成BCryptPasswordEncoder密码
     *
     * @param password 密码
     * @return 加密字符串
     */
    public static String encryptPassword(String password)
    {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        return passwordEncoder.encode(password);
    }

    /**
     * 判断密码是否相同
     *
     * @param rawPassword 真实密码
     * @param encodedPassword 加密后字符
     * @return 结果
     */
    public static boolean matchesPassword(String rawPassword, String encodedPassword)
    {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        return passwordEncoder.matches(rawPassword, encodedPassword);
    }

    public static void createToken(LoginUser apiLoginUser) {
        String token = IdUtils.fastUUID();
        apiLoginUser.setToken(token);
        refreshToken(apiLoginUser);
    }
    public static String createToken(Long userId) {

       return  refreshToken(userId);
    }

    private static void refreshToken(LoginUser loginUser) {
        loginUser.setLoginTime(System.currentTimeMillis());
        loginUser.setExpireTime(loginUser.getLoginTime() + Constants.API_TOKEN_EXPIRY * Constants.API_TOKEN_MILLIS_TIMEUNIT);
        String userKey = getTokenKey(loginUser.getToken());
        String userRoleKey = getRoleTokenKey(loginUser.getToken());
        SpringUtils.getBean(RedisCache.class).setCacheObject(userKey, loginUser, Constants.API_TOKEN_EXPIRY, Constants.API_TOKEN_TIMEUNIT);
        SpringUtils.getBean(RedisCache.class).setCacheObject(userRoleKey, loginUser.getRole(), Constants.API_TOKEN_EXPIRY, Constants.API_TOKEN_TIMEUNIT);

    }
    private static String refreshToken(Long userId) {
        String userKey = getTokenKey(userId.toString());
        String token=IdUtils.fastSimpleUUID();
        SpringUtils.getBean(RedisCache.class).setCacheObject(userKey,token , Constants.API_TOKEN_EXPIRY, Constants.API_TOKEN_TIMEUNIT);
        SpringUtils.getBean(RedisCache.class).setCacheObject(userKey,token , Constants.API_TOKEN_EXPIRY, Constants.API_TOKEN_TIMEUNIT);
        return  token;
    }
    private static String getTokenKey(String uuid)    {
        return API_TOKEN_KEY +uuid;
    }
    public static String getRoleTokenKey(String uuid)
    {
        return API_TOKEN_ROLE_KEY + uuid;
    }
}
